//
//  XMLReadEventLogs.m
//  Seizure
//
//  Reads XML of Patient Event Logs
//
//  <log>
//      <start> </start>
//      <end>   </end>
//      <latitude> </latitude>
//      <longitude> </longitude>
//      <accuracy> </accuracy>
//  </log>
//
//  Created by student on 3/27/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import "XMLReadEventLogs.h"
#import "EventLog.h"

@implementation XMLReadEventLogs

@synthesize currentElementValue;
@synthesize allEvents;
@synthesize event;

    typedef enum {
        blank,
        logStart,
        start,
        end,
        latitude,
        longitude,
        accuracy
    } CurrentElement;

    CurrentElement curr_state = blank;
    BOOL insidePatientLog = NO;

    static NSString *xLog = @"log",
                    *xStart = @"start",
                    *xEnd = @"end",
                    *xLatitude = @"latitude",
                    *xLongitude = @"longitude",
                    *xAccuracy = @"accuracy";

    NSMutableString *xml;
    NSNumber *lat_reusable;
    NSNumber *long_reusable;
    NSNumber *acc_reusable;

- (NSMutableString *)xml
{
    return xml;
}

//initialize things
- (id) init
{
    xml = [[NSMutableString alloc] init];
    lat_reusable = [[NSNumber alloc] initWithInt:0];
    long_reusable = [[NSNumber alloc] initWithInt:0];
    acc_reusable = [[NSNumber alloc] initWithInt:0];
    
    if( self = [super init] )
    {
        event = [[EventLog alloc] init];
        allEvents = [[NSMutableArray alloc] init];
        currentElementValue = [[NSMutableString alloc] init];
    }
    return self;
}


#pragma mark -- NSXMLParserDelegate methods

// enters <element>
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI
 qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
    if( [elementName isEqualToString:xLog] )
    {
        //NSLog(@"Entering Log");
        insidePatientLog = YES;
    }
    else if( [elementName isEqualToString:xStart] && insidePatientLog ) //inside <start>
    {
        curr_state = start;
    }
    else if( [elementName isEqualToString:xEnd] && insidePatientLog )   //inside <end>
    {
        curr_state = end;
    }
    else if( [elementName isEqualToString:xLatitude] && insidePatientLog )  //inside <latitude>
    {
        curr_state = latitude;
    }
    else if( [elementName isEqualToString:xLongitude] && insidePatientLog ) //inside <longitude>
    {
        curr_state = longitude;
    }
    else if( [elementName isEqualToString:xAccuracy] && insidePatientLog )  //inside <accuracy>
    {
        curr_state = accuracy;
    }
}

// exits <element>
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI
 qualifiedName:(NSString *)qName
{
    if( [elementName isEqualToString:xLog] )    //end of log
    {   
        //Add the event location to the temporary event.
        CLLocationCoordinate2D coords = CLLocationCoordinate2DMake(lat_reusable.doubleValue, 
                                                                    long_reusable.doubleValue);
        event.locationOfEvent = [[CLLocation alloc] initWithCoordinate:coords altitude:0 horizontalAccuracy:acc_reusable.doubleValue verticalAccuracy:0 timestamp:nil];
        
//        NSLog(@" Start: %@ End: %@ Lat %f Long: %f Acc: %f", event.startTime, event.endTime, event.locationOfEvent.coordinate.latitude, event.locationOfEvent.coordinate.longitude, event.locationOfEvent.horizontalAccuracy);
        
        [allEvents addObject:[[EventLog alloc] init:event.startTime end:event.endTime location:event.locationOfEvent]];
        
//        NSLog(@" Start: %@ End: %@ Lat %f Long: %f Acc: %f", ((EventLog*)[allEvents objectAtIndex:0]).startTime, ((EventLog*)[allEvents objectAtIndex:0]).endTime, ((EventLog*)[allEvents objectAtIndex:0]).locationOfEvent.coordinate.latitude, ((EventLog*)[allEvents objectAtIndex:0]).locationOfEvent.coordinate.longitude, ((EventLog*)[allEvents objectAtIndex:0]).locationOfEvent.horizontalAccuracy);
      
        event.startTime = nil;
        event.endTime = nil;
        event.locationOfEvent = nil;
        lat_reusable = nil;
        long_reusable = nil;
        acc_reusable = nil;
    }
    else if( [elementName isEqualToString:xStart] && insidePatientLog )  //exit <start>
    {
        //NSLog(@"XML:'%@',Current Element:'%@'", xml, currentElementValue);
        //Get the string representation of the date from the xml
        NSString *dateString = [[NSString alloc] initWithString:[currentElementValue copy]];
       
        //NSLog(@"%@",dateString);
        //Create a date formatter that uses a format string which looks for the necessary pattern.
        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        //Example date: 2012-01-26 05:00:00
        NSString *formatString = [[NSString alloc] initWithString:@"yyyy-MM-dd HH:mm:ss"];
        [dateFormatter setDateFormat:formatString];
        
        //Create an NSDate from the string representation using the specified format
        NSDate *date = [dateFormatter dateFromString:dateString];
        //NSLog(@"%@", date);
        event.startTime = date;
    }
    else if( [elementName isEqualToString:xEnd] && insidePatientLog )   //exit <end>
    {
        //NSLog(@"XML:'%@',Current Element:'%@'", xml, currentElementValue);
        //See notes about start above for how this works.
        NSString *dateString = [[NSString alloc] initWithString:[currentElementValue copy]];
        dateString = [dateString substringFromIndex:1];
        
        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        NSString *formatString = [[NSString alloc]initWithString:@"yyyy-MM-dd HH:mm:ss"];
        [dateFormatter setDateFormat:formatString];
        
        NSDate *date = [dateFormatter dateFromString:dateString];
        //NSLog(@"%@", date);
        event.endTime = date;
    }
    
    else if( [elementName isEqualToString:xLatitude] && insidePatientLog ) //exit <latitude>
    {
        NSNumberFormatter *f = [[NSNumberFormatter alloc] init];
        [f setNumberStyle:NSNumberFormatterDecimalStyle];
        
        //Get the string representation of the latitude. This string has a prefacing whitespace break line character.
        NSString *latitudeString = [currentElementValue copy];
        //Remove new line character so latitudeString has JUST the latitude now.
        latitudeString = [latitudeString substringFromIndex:1];
        
        //make an NSNumber representation of the latitude from the string representation.
        lat_reusable = [[NSNumber alloc] initWithDouble:[f numberFromString:latitudeString].doubleValue];
        //NSLog(@"Latitude: %@", lat_reusable);
    }
    else if( [elementName isEqualToString:xLongitude] && insidePatientLog ) //exit <longitude>
    {
        //See notes about latitude for why the conversion is done this way.
        NSNumberFormatter *f = [[NSNumberFormatter alloc] init];
        [f setNumberStyle:NSNumberFormatterDecimalStyle];
        
        NSString *longitudeString = [currentElementValue copy];
        longitudeString = [longitudeString substringFromIndex:1];
        
        long_reusable = [f numberFromString:longitudeString];
        //NSLog(@"Longitude: %@", long_reusable);
    }
    else if( [elementName isEqualToString:xAccuracy] && insidePatientLog )  //exit <accuracy>
    {
        NSString *accuracyString = [currentElementValue copy];
        //Gets rid of leading newline
        accuracyString = [accuracyString substringFromIndex:1];
        
        NSNumberFormatter *f = [[NSNumberFormatter alloc] init];
        [f setNumberStyle:NSNumberFormatterDecimalStyle];
        
        acc_reusable = [f numberFromString:accuracyString];
    }
    
    currentElementValue = [NSMutableString stringWithString:@""];
}


- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    if( curr_state != blank )
    {
        [currentElementValue appendString:string];
    }
    
    [xml appendString:string];
}


@end
